#pragma once
#ifndef ACOMBINE_FUNC_H 
#define ACOMBINE_FUNC_H 
#include <string> 
#include <iostream>
#include <vector>
#include <algorithm>

#include "TH1.h"
#include "TSystem.h"
#include "TStyle.h"
#include "TCanvas.h"
#include "TChain.h"
#include "TClonesArray.h"


#include "classes/DelphesClasses.h"

#include "ExRootTreeReader.h"
#include "ExRootResult.h"


class ExRootResult;
class ExRootTreeReader;

#include "src/Lib/libstructure.h"
#include "src/Class/ACut.h"
#include "src/Class/AComb_LTV.h"
#include "src/Class/AAngle_Inter.h"
#include "src/Lib/MessageFormat.h"
#include "src/Function/Fbasic.h"
#include "src/Function/Fvector.h"
#include "src/Function/FTLorentzVector.h"
#include "src/Class/DrawClass.h"
#include "src/AnalyseClass/AnalyseClass.h"
#include "src/AnalyseClass/Object.h"
#include "src/Analyse/Abasic.h"
#include "src/Analyse_Combine/AN_rc_w_lnu.h"
#include "src/Analyse_Combine/Arecoil.h"
#include "src/Analyse_Combine/Acomb_recoil.h"


bool Combine2_direct(TLorentzVector mom1, TLorentzVector mom2,float cut_mlow, float cut_mup, float cut_ptlow, float cut_ptup, float *mass_re);

bool Find_ximin(float *xi_min,float input1,float obj1,float input2,float obj2, float *output1,float *output2);

template <typename TParticle>
bool Combine2SameFS(CDraw &para, TH1 *comb, std::vector<TParticle>  &in,float obj_mass, float cut_mlow, float cut_mup, float cut_ptlow, float cut_ptup, std::vector<TParticle> &choosed, std::vector<TParticle> &left){

	std::vector<TLorentzVector> LTV_in;
	for(int i=0;i<LTV_in.size();i++){
		LTV_in.push_back(in->P4());
	} 
	bool JComb=Combine2SameFS_TLorentzvector(para, in, obj_mass, cut_mlow, cut_mup, cut_ptlow, cut_ptup, choosed, left);
	return(true);
}


bool Combine2SameFS_TLorentzvector(CDraw &para, TH1 *comb, std::vector<TLorentzVector> &in,float obj_mass, float cut_mlow, float cut_mup, float cut_ptlow, float cut_ptup, TLorentzVector &choosed);

bool Combine2DifferentFS_TLorentzvector(CDraw &para, TH1 *comb, std::vector<TLorentzVector> in1,std::vector<TLorentzVector> &in2,float obj_mass, float cut_mlow, float cut_mup, float cut_ptlow, float cut_ptup, TLorentzVector &choosed);

bool Combine4SameFS_TLorentzvector(CDraw &para, TH1 *comb1, TH1 *comb2, std::vector<TLorentzVector> &in,
		float obj_mass1, float obj_mass2,
		float cut_mlow1, float cut_mup1, float cut_ptlow1, float cut_ptup1,
		float cut_mlow2, float cut_mup2, float cut_ptlow2, float cut_ptup2,
		std::vector<TLorentzVector> &choosed);

bool CombineMoreWith2DifferentFS_TLorentzvector(CDraw &para, TH1 *comb, std::vector<TLorentzVector> &in1,std::vector<TLorentzVector> &in2, float obj_mass, std::vector<TLorentzVector> &Vcombine);

bool Combine2DifferentAngles_TLorentzvector(CDraw &para, TH1 *comb, std::vector<TLorentzVector> &in1, std::vector<TLorentzVector> &in2, std::vector<float> &Values);
bool Combine2DifferentMT_TLorentzvector(CDraw &para, TH1 *comb, std::vector<TLorentzVector> &in1, std::vector<TLorentzVector> &in2, std::vector<float> &Values);
bool CombineSameAngles_TLorentzvector(CDraw &para, TH1 *comb, std::vector<TLorentzVector> &in1, std::vector<float> &Values);
#endif
